package admin.core.utils;

import admin.core.annotation.Query;
import admin.core.annotation.TableField;
import admin.core.annotation.TableId;
import admin.core.annotation.TableName;
import admin.core.enums.IdType;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AnnotationUtils {
    public static List<Field> getAnnotatedFields(Class<?> clazz) {
        List<Field> fields = new ArrayList<>();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(TableField.class) || field.isAnnotationPresent(TableId.class)) {
                fields.add(field);
            }
        }
        return fields;
    }


    public static Field getIdField(Class<?> clazz) {
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(TableField.class) || field.isAnnotationPresent(TableId.class)) {
                return field;
            }
        }
        return null;
    }

    public static String getLabelName(Field field) {
        if (field.isAnnotationPresent(TableField.class)) {
            TableField annotation = field.getAnnotation(TableField.class);
            return annotation.label();
        } else if (field.isAnnotationPresent(TableId.class)) {
            TableId annotation = field.getAnnotation(TableId.class);
            return annotation.label().isEmpty() ? field.getName() : annotation.label();
        }
        return field.getName();
    }

    public static String getColumnValue(Field field) {
        if (field.isAnnotationPresent(TableField.class)) {
            TableField annotation = field.getAnnotation(TableField.class);
            return annotation.value().isEmpty() ? field.getName() : annotation.value();
        } else if (field.isAnnotationPresent(TableId.class)) {
            TableId annotation = field.getAnnotation(TableId.class);
            return annotation.value().isEmpty() ? field.getName() : annotation.value();
        }
        return field.getName();
    }

    public static String getTableName(Class<?> clazz) {
        if (clazz.isAnnotationPresent(TableName.class)) {
            TableName annotation = clazz.getAnnotation(TableName.class);
            return annotation.label();
        }
        return "";
    }

    public static String getTableNameValue(Class<?> clazz) {
        if (clazz.isAnnotationPresent(TableName.class)) {
            TableName annotation = clazz.getAnnotation(TableName.class);
            return annotation.value();
        }
        return "";
    }

    public static String getTableIdValue(Class<?> clazz) {
        Field idField = getIdField(clazz);
        assert idField != null;
        TableId annotation = idField.getAnnotation(TableId.class);
        return annotation.value().isEmpty() ? idField.getName() : annotation.value();
    }

    public static List<String> getColumnNames(Class<?> clazz) {
        List<String> columnNames = new ArrayList<>();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(TableField.class)) {
                TableField annotation = field.getAnnotation(TableField.class);
                columnNames.add(annotation.label());
            } else if (field.isAnnotationPresent(TableId.class)) {
                TableId annotation = field.getAnnotation(TableId.class);
                columnNames.add(annotation.label().isEmpty() ? field.getName() : annotation.label());
            }
        }
        return columnNames;
    }

    public static Object[] getRowData(Object item, Field[] fields) {
        List<Object> row = new ArrayList<>();
        for (Field field : fields) {
            field.setAccessible(true);
            if (field.isAnnotationPresent(TableField.class) || field.isAnnotationPresent(TableId.class)) {
                try {
                    row.add(field.get(item));
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        row.add("查看"); // 为“查看”按钮预留位置
        return row.toArray();
    }

    public static <E> IdType getIdType(Class<E> Clazz) {
        Field idField = AnnotationUtils.getIdField(Clazz);
        assert idField != null;
        TableId annotation = idField.getAnnotation(TableId.class);
        return annotation.type();
    }

    public static <T> List<Map<String, Object>> getSearchFields(Class<T> clazz) {
        List<Map<String, Object>> fields = new ArrayList<>();
        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(Query.class)) {
                Map<String, Object> f = new HashMap<>();
                f.put("type", field.getAnnotation(Query.class).value());
                f.put("column", getColumnValue(field));

                fields.add(f);
            }
        }
        return fields;
    }
}
